'''
This file defines all constants used by the GUI and game
'''

# imports
from Tkinter import *

import cPickle as pickle
import Queue
import socket
import threading
import time
import sys
import math
import tkFileDialog
import random

# server constants
BUFF = 1024
HOSTING = 'hosting'
WAITING = 'waiting'
TURN_OVER = 'turn over'
RESPONSE = 'response'

# message constants
PLAYER = 'player'
BOARD = 'board'
RULES = 'rules'

# sends message to the server
def SEND_TO_SERVER(sock, msg):
    send = pickle.dumps(msg)
    size = str(sys.getsizeof(send))
    sock.sendall(size)
    passed = sock.recv(BUFF)
    if passed == 'passed':
        sock.sendall(send)
    else:
        print 'socket error'
        sys.exit()

# returns message from server
def RECV_FROM_SERVER(sock):
    size = sock.recv(BUFF)
    recv = sock.recv(int(size))
    try:
        msg = pickle.loads(recv)
    except EOFError:
        pass
    return msg

# sends message from server to client
def SEND_TO_CLIENT(sock, msg):
    send = pickle.dumps(msg)
    size = str(sys.getsizeof(send))
    sock.sendall(size)
    time.sleep(0.1)
    sock.sendall(send)
    
# rotation
N = 0
E = 1
S = 2
W = 3

# square owners
A = 'Area_'
B = 'Border'
O = 'Overlap'
P = 'Current_Piece'
P1 = 'Player 1'
P2 = 'Player 2'
P3 = 'Player 3'
P4 = 'Player 4'
C = 'Cathedral'
T = '_Territory'
NT = 'Neutral' + T
P1T = P1 + T
P2T = P2 + T
P3T = P3 + T
P4T = P4 + T
TIE = 'Tie'

def GET_PLAYER_NUM(player):
    if player == P1:
        num = 0
    if player == P2:
        num = 1
    if player == P3:
        num = 2
    if player == P4:
        num = 3
    return num    
    
def GET_PLAYER_STR(num):
    return 'Player %d' % (num + 1)
    
def NEXT_TURN(player, numPlayers):
    return GET_PLAYER_STR((GET_PLAYER_NUM(player) + 1) % numPlayers)

def PREV_TURN(player, numPlayers):
    return GET_PLAYER_STR((GET_PLAYER_NUM(player) + numPlayers - 1) % numPlayers)

# initial board size
SQUARE_SIZE = 40

# returns Tkinter formatted rgb color
def GET_COLOR(r, g, b):
    return '#%02x%02x%02x' % (r, g, b)
    
# default colors
DEF_P1             = GET_COLOR(205, 170, 125) # burlywood3
DEF_P1_TER         = GET_COLOR(255, 211, 155) # burlywood1
DEF_P2             = GET_COLOR(139,  90,  43) # tan4
DEF_P2_TER         = GET_COLOR(205, 133,  63) # tan3
DEF_P3             = GET_COLOR(205, 170, 125) # burlywood3
DEF_P3_TER         = GET_COLOR(255, 211, 155) # burlywood1
DEF_P4             = GET_COLOR(139,  90,  43) # tan4
DEF_P4_TER         = GET_COLOR(205, 133,  63) # tan3
DEF_CATH           = GET_COLOR(112, 128, 144) # SlateGrey
DEF_CURR_PIECE     = GET_COLOR(191, 191, 191) # grey75
DEF_CONFLICT_PIECE = GET_COLOR(165,  42,  42) # Brown
DEF_BOARD          = GET_COLOR(255, 248, 220) # cornsilk
DEF_P1_STIP      = ''
DEF_P1_TER_STIP  = 'gray75'
DEF_P2_STIP      = ''
DEF_P2_TER_STIP  = 'gray75'

# returns the territory name of a particular owner
def TER(owner):
    return owner + T

# returns correct multipiers and swap x / y for each direction
def REORIENT(orientation, geometry):
    if orientation == N:
        swap = False
        xMult = 1
        yMult = 1
    elif orientation == S:
        swap = False
        xMult = -1
        yMult = -1
    elif orientation == E:
        swap = True
        xMult = 1
        yMult = -1
    elif orientation == W:
        swap = True
        xMult = -1
        yMult = 1
    newGeo = []
    for (x,y) in geometry:
        if swap:
            newGeo.append((y * xMult, x * yMult))
        else:
            newGeo.append((x * xMult, y * yMult))
    return newGeo

# debug print of board values
def PRINT_BOARD(squares):
    prevY = 0
    for s in squares:
        if s.y != prevY:
            print
        print TEST(s.owner),
        prevY = s.y
    print '\ndone'

# returns one char string for each board value
def TEST(x):
    if x == O:
        return 'O'
    if x == P:
        return 'P'
    if x == P2:
        return 'D'
    if x == P1:
        return 'L'
    if x == C:
        return 'C'
    if x == T:
        return 'T'
    if x == NT:
        return 'N'
    if x == P1T:
        return 'l'
    if x == P2T:
        return 'd'
    if x == B:
        return 'B'
    if x.find(A) != -1:
        return int(x.split('_')[1])

# piece geometry definition
TA_D = ('Tavern', [(0,0)])                                     #[[2]]
ST_D = ('Stable', [(0,0),( 0,-1)])                                  #[[2],[1]]
IN_D = ('Inn', [(0,0),( 0,-1),( 1,-1)])                          #[[2,0],[1,1]]
BR_D = ('Bridge', [(0,0),( 0,-1),( 0,-2)])                          #[[2],[1],[1]]
SQ_D = ('Square', [(0,0),( 1, 0),( 0,-1),( 1,-1)])                  #[[2,1],[1,1]]
MA_D = ('Manor', [(0,0),(-1,-1),( 0,-1),( 1,-1)])                  #[[0,2,0],[1,1,1]]
AB_D = ('Abby', [(0,0),(-1,-1),( 0,-1),(-1,-2)])                  #[[0,2],[1,1],[1,0]]
CS_D = ('Castle', [(0,0),(-1, 0),(-1,-1),(-1,-2),( 0,-2)])          #[[1,2],[1,0],[1,1]]
AC_D = ('Acadamy', [(0,0),( 0,-1),( 1,-1),(-1,-2),( 0,-2)])          #[[0,2,0],[0,1,1],[1,1,0]]
IF_D = ('Infirmary', [(0,0),( 0, 1),(-1, 0),( 1, 0),( 0,-1)])          #[[0,1,0],[1,2,1],[0,1,0]]
TO_D = ('Tower', [(0,0),( 0,-1),(-1,-1),(-1,-2),(-2,-2)])          #[[0,0,2],[0,1,1],[1,1,0]]
TA_L = TA_D
ST_L = ST_D
IN_L = IN_D
BR_L = BR_D
SQ_L = SQ_D
MA_L = MA_D
AB_L = ('Abby', [(0,0),( 0,-1),( 1,-1),( 1,-2)])                  #[[2,0],[1,1],[0,1]]
CS_L = CS_D
AC_L = ('Acadamy', [(0,0),(-1,-1),( 0,-1),( 0,-2),( 1,-2)])          #[[0,2,0],[1,1,0],[0,1,1]]
IF_L = IF_D
TO_L = TO_D
CA   = ('Cathedral', [(0,0),(-1,-1),( 0,-1),( 1,-1),( 0,-2),( 0,-3)])    #[[0,2,0],[1,1,1],[0,1,0],[0,1,0]]
BC   = ('Cathedral', [(0,0),( 1, 0),(-1,-1),( 0,-1),( 1,-1),( 2,-1),(-1,-2),( 0,-2),( 1,-2),( 2,-2),( 0,-3),( 1,-3)])

# Rule definitions
TEAMS = 'Teams?'
BIG_CATH = 'Big Cathedral?'
REPLACE_CATH = 'Replace Captured Cathedral?'
PLAY_TWICE = 'Teams Play Twice?' # might remove this one based on game mechanics
NUM_PLAYERS = 'How Many Players?'

# player piece lists
LIGHT_PIECES = [TA_L, TA_L, ST_L, ST_L, IN_L, IN_L, BR_L, SQ_L, MA_L, AB_L, CS_L, AC_L, IF_L, TO_L]
DARK_PIECES  = [TA_D, TA_D, ST_D, ST_D, IN_D, IN_D, BR_D, SQ_D, MA_D, AB_D, CS_D, AC_D, IF_D, TO_D]
P1_PIECES  =   [TA_L, ST_L, ST_L, IN_L, IN_L, BR_L, SQ_L, MA_L, AB_L, CS_L, AC_L, IF_L, TO_L]
P2_PIECES  =   [TA_D, ST_D, ST_D, IN_D, IN_D, BR_D, SQ_D, MA_D, AB_D, CS_D, AC_D, IF_D, TO_D]
P3_PIECES  =   [TA_L, ST_L, ST_L, IN_L, IN_L, BR_L, SQ_L, MA_L, AB_L, CS_L, AC_L, IF_L, TO_L]
P4_PIECES  =   [TA_D, ST_D, ST_D, IN_D, IN_D, BR_D, SQ_D, MA_D, AB_D, CS_D, AC_D, IF_D, TO_D]

# returns letter for x value in board
def LOC_NOT(x, y):
    enum = {0 : 'A', 1 : 'B', 2 : 'C', 3 : 'D', 4 : 'E', 5 : 'F', 6 : 'G', 7 : 'H', 8 : 'I', 9 : 'J', 10: 'K', 11 : 'L', 12 : 'M', 13 : 'N', 14 : 'O', 15 : 'P', 16 : 'Q', 17 : 'R', 18 : 'S', 19 : 'T', 20 : 'U', 21 : 'V', 22 : 'W', 23 : 'X', 24 : 'Y', 25 : 'Z'}
    return '%s%d' % (enum[x], y + 1)

# returns direction letter for rotation of played piece
def DIR_NOT(direction):
    enum = {N : 'e', S : 'w', E : 's', W : 'n'}
    return enum[direction]

# returns piece name shorthand for placed piece
def PEICE_NOT(name):
    enum = {'Tavern' : 'TA', 'Stable' : 'ST', 'Inn' : 'IN', 'Bridge' : 'BR', 'Square' : 'SQ', 'Manor' : 'MA', 'Abby' : 'AB', 'Castle' : 'CS', 'Acadamy' : 'AC', 'Infirmary' : 'IF', 'Tower' : 'TO', 'Cathedral' : 'CA'}
    return enum[name]